/*
 * @Author: DUST
 * @Date: 2023-06-20 09:29:23
 * @LastEditors: DUST
 * @LastEditTime: 2023-06-27 13:50:40
 * @FilePath: \vite-project\src\utils\ckThree\index.js
 * @Description: 
 * undefined
 */
import * as THREE from "three";
import {
  Scene,
  Group,
  DoubleSide,
  Color,
  OrthographicCamera,
  Box3,
  Vector3,
  GridHelper,
  Box3Helper,
  Object3D,
} from "three";

import initCamera from "./camera.js";
import initLight from "./light.js";
import initRenderer from "./sceneRender.js";
import initControl from "./orbitcontrols.js";
import initDragControls from "./dragControls.js";
import loadGltf, {
  loadAllGltfPoint,
  addGltfModelPoint
} from "./loadGltf.js";

import {
  move2Center,
  onMouseClick,
  toolTips,
  transPosition,
  removeToolTips,
  diffusionCylinder,
  createTriangularPyramid,
  addTubeLine,
  loadTexture
} from "./utils";

import { clearGroup } from "./cleanObj.js";
import { loadTextures, loadSpriteMarker, loadSpriteMarkers } from "./spriteMarker.js";

class ckThree {
  constructor({
    contanierDom,
    modelOPtions,
    width,
    height,
    randendCall,
    dragControlsCallBackOptions = {},
  }, progress) {
    this.animationId = undefined;
    // 组合
    this.Group = Group;
    // 场景
    this.scene = new Scene();
    // 宽高
    this.width = width;
    this.height = height;
    // 模型数据
    this.modelOptions = modelOPtions;
    // 相机
    this.camera = initCamera(this.scene, width, height, modelOPtions.options.cameraOptions);

    // 灯光
    const lightObj = initLight(this.scene);
    this.ambientLight = lightObj.ambientLight;
    this.dlight = lightObj.dlight;

    // 渲染器
    this.renderer = initRenderer(contanierDom, width, height);

    // 控制器
    this.control = initControl(this.renderer, this.camera);

    // 工具模型
    this.modelContainer = new Object3D();
    this.modelContainer.name = "modelContainer";
    this.scene.add(this.modelContainer);

    this.utilsGroup = new Group();
    this.utilsGroup.name = "utilsModel"
    this.scene.add(this.utilsGroup);

    // 精灵图标组合
    this.spriteGroup = new Group();
    this.spriteGroup.name = "spriteGroup";
    this.scene.add(this.spriteGroup);

    // 拖拽控制器
    this.dragControls = initDragControls(
      this.spriteGroup.children,
      this.scene,
      this.renderer,
      this.camera,
      this.control,
      dragControlsCallBackOptions
    );
    this.dragControls.enabled = false; //关闭拖拽

    // 场景大模型
    this.objGroup = new Group();
    this.objGroup.name = "sceneModel"
    this.scene.add(this.objGroup);

    // 扩散圆柱
    this.cylinderGroup = new Group();
    this.cylinderGroup.name = "cylinder"
    this.scene.add(this.cylinderGroup);

    // 模型加载进度条
    if (progress) this.progress = progress;
    else this.progress = (xhr) => {
      // console.log("加载完成的百分比" + (xhr.loaded / xhr.total) * 100 + "%");
      this.precent = ((xhr.loaded / xhr.total) * 100).toFixed(2);
      this.loadingGltf = false;
      if ((xhr.loaded / xhr.total) * 100 == 100) {
        this.loadingGltf = true;
      }
      console.log("progress", this);
    }

    // 模型加载回调
    this.modelCallback = (obj) => {
      obj.scene.traverse((child) => {
        child.castShadow = true;
        child.receiveShadow = true;
        if (child.material) {
          child.material.transparent = true;
          child.material.side = DoubleSide;
        }
      });

      obj.scene.scale.set(1.5, 1.5, 1.5);
      move2Center(obj.scene);
      // 加载工具模型
      // loadAllGltfPoint(this.modelContainer, modelOPtions.monitorPoints, (gltf) => {
      //   gltf.name = "utilsGltf"
      //   gltf.visible = false;
      //   this.utilsGroup.add(gltf)
      // });

      this.objGroup.add(obj.scene);
      this.render();
    }
    this.sceneModel = loadGltf(modelOPtions, this.progress, this.modelCallback)

    // 开启页面帧率刷新
    this.render = () => {
      // this.circleAnimate();
      // stats.update();
      // const delta = clock.getDelta(); //获取自上次调用的时间差
      // controls.update(delta) //控制器更新
      cancelAnimationFrame(this.animationId);
      // this.cylinderAnimate(); //圆柱光圈扩散更新
      // this.spriteAnimate();
      this.control.update();
      this.renderer.render(this.scene, this.camera);
      this.animationId = requestAnimationFrame(this.render);
      // console.log("角度:",this.camera.position);
      // ();
      if(randendCall) randendCall();
    }
    // 资源释放
    this.dispose = (randenderDom) => {
      // 释放拖拽控制器
      if(this.dragControls) {
        this.dragControls.dispose();
        this.dragControls =  null;
      }
      // 释放轨道控制器
      if(this.control) {
        this.control.dispose();
        this.control =  null;
      }
      
      //根据动画id停止动画渲染
      cancelAnimationFrame(this.animationId);
      this.animationId = undefined;
      // 释放场景资源
      this.scene.traverse((child) => {
        if (child.material) {
          if(Object.prototype.toString.call(child.material) == "[object Array]") {
            child.material.forEach(element => {
              element.dispose();
            });
          }
          else child.material.dispose();
        }
        if (child.geometry) {
          child.geometry.dispose();
        }
        child = null;
      });
      // 清除组合资源
      clearGroup(this.modelContainer);
      clearGroup(this.objGroup);
      clearGroup(this.cylinderGroup);
      clearGroup(this.utilsGroup);
      clearGroup(this.spriteGroup);
      // 清除场景中组合
      this.scene.remove(this.modelContainer)
      this.scene.remove(this.objGroup)
      this.scene.remove(this.cylinderGroup)
      this.scene.remove(this.utilsGroup)
      this.scene.remove(this.spriteGroup)
      // 组合置空
      this.modelContainer = null;
      this.objGroup = null;
      this.cylinderGroup = null;
      this.utilsGroup = null;
      this.spriteGroup = null;

      //强制失去上下文
      this.renderer.forceContextLoss();
      this.renderer.dispose();
      // 清空场景
      this.scene.clear();
      this.scene = null;
      // 销毁相机
      this.camera = null;
      // 清空渲染节点
      document.getElementById(randenderDom).innerHTML = null;
      // 清空渲染器
      this.renderer = null;
    }

    // 绑定工具
    this.toolTips = toolTips; 
    this.removeToolTips = removeToolTips; 
    // 三维坐标转屏幕坐标
    this.transPosition = transPosition;
    // 点击事件
    this.onMouseClick = onMouseClick;
    // 往对应点位添加模型点标记
    this.addGltfModelPoint = addGltfModelPoint;
    // 扩散圆柱对象
    this.diffusionCylinder = diffusionCylinder;
    // 创建三棱锥
    this.createTriangularPyramid = createTriangularPyramid;
    // 加载材质
    this.loadTexture = loadTexture;
    // 创建流动管道
    this.addTubeLine = addTubeLine;
    // 加载贴图素材集合
    this.loadTextures = loadTextures;
    // 加载精灵图标
    this.loadSpriteMarker = loadSpriteMarker;
    // 加载精灵图标集合
    this.loadSpriteMarkers = loadSpriteMarkers;

  }

  // /**
  //  * @description: 添加toolTips提示
  //  * @param {*} data:需要展示的数据
  //  */
  // static toolTips(data) {
  //   if (document.getElementById("modal")) {
  //     document.body.removeChild(document.getElementById("modal"));
  //   }
  //   const dom = document.createElement("div");
  //   dom.id = "modal";
  //   dom.style.position = "absolute";
  //   dom.style.left = point.x - 60 + "px";
  //   // dom.style.top = point.y - 60 + "px";
  //   dom.style.backgroundColor = "#00ff00";
  //   dom.style.padding = "5px";
  //   dom.innerHTML = "这是一个提示框";
  //   document.body.appendChild(dom);
  // }

}

export default ckThree;